package com.leozhang.app;

import cn.hutool.core.date.DateUtil;
import org.apache.commons.cli.*;

import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.Instant;
import java.util.Date;

public class CRLicenseGenerator {
    private static final String PRIVATE_KEY_PATH = "keys/cr_license_key";

    public static void main(String[] args) {
        Options options = new Options();

        options.addOption("i", "input", true, "License 文件路径");
        options.addOption("o", "output", true, "输出证书文件路径");
        options.addOption("d", "licenseDays", true, "License 过期天数 (默认 100)");
        options.addOption("m", "maintenanceDays", true, "维护期天数 (默认 100)");
        options.addOption("c", "customerName", true, "客户名称");
        options.addOption("s", "modules", true,
                "授权的模块 (默认 training,simulation,drills,match,penetrant,recurrent)");
        options.addOption("t", "type", true, "许可证类型 (默认 enterprise)");
        options.addOption("u", "userNum", true, "用户数量 (默认 1000)");

        CommandLineParser parser = new DefaultParser();
        try {
            CommandLine cmd = parser.parse(options, args);

            if (!cmd.hasOption("i") || !cmd.hasOption("o")) {
                System.out.println("使用方式: java CRLicenseGenerator -i <licenseFilePath> -o <outputFilePath> [可选参数]");
                new HelpFormatter().printHelp("LicenseGenerator", options);
                return;
            }

            String licenseFilePath = cmd.getOptionValue("i");
            String outputFilePath = cmd.getOptionValue("o");

            // 读取 License 文件内容
            String licenseContent = new String(Files.readAllBytes(Paths.get(licenseFilePath))).trim();
            System.out.println("License content: " + licenseContent);
            byte[] licenseContentBytes = Base64.decode(licenseContent);

            // 读取PrivateKey内容
            String licenseKeyString = new String(Files.readAllBytes(Paths.get(PRIVATE_KEY_PATH))).trim();
            RSA rsa = new RSA(licenseKeyString, null);

            // 解密 License 内容
            byte[] decryptedLicenseContentBytes = rsa.decrypt(licenseContentBytes, KeyType.PrivateKey);
            String decryptedLicenseContent = StrUtil.str(decryptedLicenseContentBytes, CharsetUtil.CHARSET_UTF_8);
            // System.out.println("Decrypted license content: " + decryptedLicenseContent);

            JSONObject licJsonObject = JSONUtil.parseObj(decryptedLicenseContent);
            // System.out.println("Decrypted license content: " + licJsonObject);
            // Date issuedDate = null;
            // if (licJsonObject.getIssuedDate() == null) {
            //     DateTime dateTime = DateUtil.date();
            // } else {
            //     issuedDate = licenseVO.getIssuedDate();
            // }
            Date issuedDate = DateUtil.date();
            // System.out.println("Issued date: " + issuedDate);

            // 获取命令行参数或默认值
            int licenseDays = Integer.parseInt(cmd.getOptionValue("d", "100"));
            int maintenanceDays = Integer.parseInt(cmd.getOptionValue("m", "100"));
            String customerName = cmd.getOptionValue("c", "LeoZhang");
            String modules = cmd.getOptionValue("s", "training,simulation,drills,match,penetrant,recurrent,testing");
            String type = cmd.getOptionValue("t", "enterprise");
            int userNum = Integer.parseInt(cmd.getOptionValue("u", "100"));

            JSONObject outputJsonObject = JSONUtil.createObj()
                    .set("productSerialNumber", licJsonObject.getStr("productSerialNumber"))
                    .set("productName", licJsonObject.getStr("productName"))
                    .set("productVersion", licJsonObject.getStr("productVersion"))
                    .set("issuedDate", DateUtil.format((Date) DateUtil.offsetHour(issuedDate, -8), "yyyyMMddHHmmss"))
                    .set("expiredDate",
                            DateUtil.format((Date) DateUtil.offsetDay((Date) DateUtil.offsetHour(issuedDate, -8),
                                    licenseDays), "yyyyMMddHHmmss"))
                    .set("maintenanceStartDate",
                            DateUtil.format((Date) DateUtil.offsetHour(issuedDate, -8), "yyyyMMddHHmmss"))
                    .set("maintenanceEndDate",
                            DateUtil.format((Date) DateUtil.offsetDay((Date) DateUtil.offsetHour(issuedDate, -8),
                                    maintenanceDays), "yyyyMMddHHmmss"))
                    .set("customerName", customerName)
                    .set("type", type)
                    .set("modules", modules)
                    .set("userNum", userNum);
            String authorizedContent = outputJsonObject.toStringPretty();
            // System.out.println("Unauthorized content: " + authorizedContent);
            byte[] encryptedAuthContent = rsa.encrypt(StrUtil.bytes(authorizedContent, CharsetUtil.CHARSET_UTF_8), KeyType.PrivateKey);
            String encryptedAuthContentBase64 = Base64.encode(encryptedAuthContent);
            System.out.println("Encrypted authorized content: " + encryptedAuthContentBase64);
            try (FileWriter writer = new FileWriter(outputFilePath)) {
                writer.write(encryptedAuthContentBase64);
            }

            // System.out.println("证书生成成功，已保存至：" + outputFilePath);
        } catch (ParseException e) {
            System.err.println("命令行参数解析失败：" + e.getMessage());
        } catch (IOException e) {
            System.err.println("读取 License 文件失败：" + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("证书生成失败！");
        }
    }
}
